/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.builtincomponents.SecretLevel;

import com.inspur.edp.bef.api.action.determination.IQueryDeterminationContext;
import com.inspur.edp.bef.core.determination.QueryDeterminationContext;
import com.inspur.edp.bef.spi.action.determination.AbstractQueryDetermination;
import com.inspur.edp.cef.entity.condition.EntityFilter;
import com.inspur.edp.cef.entity.condition.ExpressCompareType;
import com.inspur.edp.cef.entity.condition.ExpressRelationType;
import com.inspur.edp.cef.entity.condition.FilterCondition;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.DataTypePropertyInfo;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.ObjectType;
import com.inspur.edp.cef.spi.entity.resourceInfo.builinImpls.CefEntityResInfoImpl;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.sys.security.api.data.SecLevelObjSet;
import io.iec.edp.caf.sys.security.api.data.SecurityLevel;
import io.iec.edp.caf.sys.security.api.manager.SecurityRuntimeManager;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SecurityLevelB4QueryDetermination extends AbstractQueryDetermination {
    SecurityRuntimeManager securityRuntimeManager = SpringBeanUtils.getBean(SecurityRuntimeManager.class);
    public SecurityLevelB4QueryDetermination(IQueryDeterminationContext context) {
        super(context);
    }

    @Override
    public void execute() {
        SecLevelObjSet secLevelObjSet = securityRuntimeManager.getSecLevelObjByBEId(((QueryDeterminationContext) getQueryContext()).getMgrContext().getBEManager().getBEInfo().getBEID());
        if(secLevelObjSet == null)
            return;
        SecetLevelObjSetInfo secetLevelObjSetInfo = SecretUtil.getSecretLevelObjSetInfo(secLevelObjSet);
        //有可能是密级UDT
        if(secetLevelObjSetInfo.getFieldName() == null || secetLevelObjSetInfo.getFieldName().length() == 0){
            return;
        }
        DataTypePropertyInfo secPropInfo = getSecretPropertyInfo(secetLevelObjSetInfo.getFieldName());
        if(secPropInfo == null){
            return;
        }
        if(secPropInfo.getObjectType() == ObjectType.Enum)
            return;
        setFilterCondition(secetLevelObjSetInfo.getFieldName(), secetLevelObjSetInfo.getFieldType());
    }

    private DataTypePropertyInfo getSecretPropertyInfo(String fieldName){
        DataTypePropertyInfo dataTypePropertyInfo = null;
        if(!(getQueryContext() instanceof QueryDeterminationContext)){
            return null;
        }
        QueryDeterminationContext queryDeterminationContext = (QueryDeterminationContext)getQueryContext();
        //rootEntityResInfo
        CefEntityResInfoImpl cefEntityResInfo = (CefEntityResInfoImpl) queryDeterminationContext.getModelResInfo().getCustomResource(queryDeterminationContext.getModelResInfo().getRootNodeCode());
        for(Map.Entry<String, DataTypePropertyInfo> propertyInfoEntry : cefEntityResInfo.getEntityTypeInfo().getPropertyInfos().entrySet()){
            if(propertyInfoEntry.getKey().equals(fieldName)){
                return propertyInfoEntry.getValue();
            }
        }

        return dataTypePropertyInfo;
    }

    private void setFilterCondition(String fieldName, String fieldType){
        //metaDataID
        QueryDeterminationContext queryDeterminationContext = (QueryDeterminationContext)getQueryContext();
        List<SecurityLevel> securityLevels = securityRuntimeManager.getCanAccessSecLevelsByBE(queryDeterminationContext.getMgrContext().getBEManager().getBEInfo().getBEID());
        FilterCondition filterCondition = new FilterCondition();
        filterCondition.setFilterField(fieldName);
        filterCondition.setCompare(ExpressCompareType.In);
        String values = "";
        if(securityLevels != null && securityLevels.size()>0){
            for(SecurityLevel securityLevel: securityLevels){
                switch (fieldType){
                    case "secLevelIdField":
                        values +=  securityLevel.getId() +"\r\n";
                        break;
                    case "secLevelField":
                        values +=  securityLevel.getSecLevel() +"\r\n";
                        break;
                    case "secLevelNameField":
                        values +=  securityLevel.getName() +"\r\n";
                        break;
                }
            }
            values = values.substring(0, values.length() -1);
        }
        filterCondition.setValue(values);

        if (getQueryContext().getFilter() == null)
            getQueryContext().setFilter(new EntityFilter());
        if (getQueryContext().getFilter().getFilterConditions() == null) {
            ArrayList<FilterCondition> filterConditions = new ArrayList<>();
            getQueryContext().getFilter().setFilterConditions(filterConditions);
        }
        if (getQueryContext().getFilter().getFilterConditions().size() > 0) {//修改最后一个的relation符号
            getQueryContext().getFilter().getFilterConditions().get(0).setLbracket(getQueryContext().getFilter().getFilterConditions().get(0).getLbracket() + "(");
            getQueryContext().getFilter().getFilterConditions().get(getQueryContext().getFilter().getFilterConditions().size() - 1).setRbracket(getQueryContext().getFilter().getFilterConditions().get(getQueryContext().getFilter().getFilterConditions().size() - 1).getRbracket() + ")");
            getQueryContext().getFilter().getFilterConditions().get(getQueryContext().getFilter().getFilterConditions().size() - 1).setRelation(ExpressRelationType.And);
        }
        getQueryContext().getFilter().getFilterConditions().add(filterCondition);
    }
}
